local skill = fk.CreateSkill {
  name = "handing__penal_code_skill",
}

Fk:loadTranslationTable{
  ["handing__penal_code_skill"] = "法经",
  ["@$handing__penal_code"] = "《法经》",
}

skill:addEffect("cardskill", {
  can_use = Util.FalseFunc,
})

skill:addEffect(fk.AfterCardsMove, {
  priority = 0,
  mute = true,
  can_trigger = function(self, event, target, player, data)
    if player.room:getBanner("hanqing__jidian") and
      player.room:getCardArea(player.room:getBanner("hanqing__jidian")[1]) == Card.Void then
      local ids = {}
      for _, move in ipairs(data) do
        if move.from and move.toArea == Card.Void then
          if move.from == player and not player.dead then
            for _, info in ipairs(move.moveInfo) do
              if info.fromArea == Card.PlayerHand and
                Fk:getCardById(info.cardId).name == "handing__penal_code" then
                event:setCostData(self, {choice = 1})
                return true
              end
            end
          end
        elseif player.seat == 1 and move.toArea == Card.DiscardPile then
          if move.moveReason == fk.ReasonJudge then
            local judge_event = player.room.logic:getCurrentEvent():findParent(GameEvent.Judge)
            if judge_event and judge_event.data.card then
              for _, info in ipairs(move.moveInfo) do
                if info.fromArea == Card.Processing and
                  table.contains(Card:getIdList(judge_event.data.card), info.cardId) then
                  table.insertIfNeed(ids, info.cardId)
                end
              end
            end
          elseif move.moveReason == fk.ReasonUse then
            local use_event = player.room.logic:getCurrentEvent():findParent(GameEvent.UseCard)
            if use_event then
              if use_event.data.card.type == Card.TypeTrick then
                local effect_events = use_event:searchEvents(GameEvent.CardEffect, 1, function (e)
                  return e.data.card == use_event.data.card and e.data.isCancellOut
                end)
                if #effect_events > 0 then
                  for _, info in ipairs(move.moveInfo) do
                    if info.fromArea == Card.Processing and
                      table.contains(Card:getIdList(use_event.data.card), info.cardId) then
                      table.insertIfNeed(ids, info.cardId)
                    end
                  end
                end
              end
            else
              local phase_event = player.room.logic:getCurrentEvent():findParent(GameEvent.Phase)
              if phase_event and phase_event.data.phase == Player.Judge then
                phase_event:searchEvents(GameEvent.CardEffect, 1, function (e)
                  if e.data.card.sub_type == Card.SubtypeDelayedTrick and e.data.isCancellOut then
                    for _, info in ipairs(move.moveInfo) do
                      if info.fromArea == Card.Processing and
                        table.contains(Card:getIdList(e.data.card), info.cardId) then
                        table.insertIfNeed(ids, info.cardId)
                      end
                    end
                  end
                end)
              end
            end
          end
        end
      end
      ids = table.filter(ids, function (id)
        return table.contains(player.room.discard_pile, id)
      end)
      ids = player.room.logic:moveCardsHoldingAreaCheck(ids)
      if #ids > 0 then
        event:setCostData(self, {choice = 2, cards = ids})
        return true
      end
    end
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local choice = event:getCostData(self).choice
    if choice == 1 then
      for _ = 1, 4 do
        if player.dead then break end
        local judge = {
          who = player,
          reason = skill.name,
          pattern = ".|.|spade",
        }
        room:judge(judge)
        if judge:matchPattern() and not player.dead then
          player:drawCards(1, skill.name)
        end
      end
    else
      local cards = event:getCostData(self).cards
      local banner = room:getBanner("@$handing__penal_code") or {}
      table.insertTableIfNeed(banner, cards)
      room:moveCardTo(cards, Card.Void, nil, fk.ReasonJustMove, skill.name, nil, true)
      banner = table.filter(banner, function (id)
        return room:getCardArea(id) == Card.Void
      end)
      room:setBanner("@$handing__penal_code", banner)
    end
  end,
})

skill:addEffect(fk.BeforeCardsMove, {
  can_refresh = function (self, event, target, player, data)
    for _, move in ipairs(data) do
      if move.from == player and move.toArea ~= Card.Void then
        for _, info in ipairs(move.moveInfo) do
          if info.fromArea == Card.PlayerHand and
            Fk:getCardById(info.cardId).name == "handing__penal_code" then
            return true
          end
        end
      end
    end
  end,
  on_refresh = function (self, event, target, player, data)
    local new_data = {}
    for _, move in ipairs(data) do
      local new_move = {}
      if #move.moveInfo > 0 and move.toArea ~= Card.Void then
        local orig_info, new_info = {}, {}
        for i = 1, #move.moveInfo do
          local info = move.moveInfo[i]
          local will_destruct = false
          if info.fromArea == Card.PlayerHand and Fk:getCardById(info.cardId).name == "handing__penal_code" then
            will_destruct = true
          end
          if will_destruct then
            table.insert(new_info, info)
          else
            table.insert(orig_info, info)
          end
        end
        move.moveInfo = orig_info
        if #new_info > 0 then
          new_move = {
            moveInfo = new_info,
            from = player,
            to = nil,
            toArea = Card.Void,
            moveReason = fk.ReasonJustMove,
            proposer = nil,
            skillName = skill.name,
            moveVisible = true,
          }
        end
      end
      if next(new_move) then
        table.insert(new_data, new_move)
      end
    end
    if next(new_data) then
      table.insertTable(data, new_data)
    end
  end,
})

return skill
